package org.robert.export_client.excel.impl;

import com.alibaba.fastjson.JSON;
import com.robert.common.commonutil.util.DateUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.ss.usermodel.CellStyle;
import org.ehcache.impl.internal.concurrent.ConcurrentHashMap;
import org.robert.export_client.excel.entity.ExcelConstant;
import org.robert.export_client.excel.metadata.*;
import org.robert.export_client.excel.util.ExcelUtil;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.util.*;

/**
 * ExcelWrtiteByDataService: 数据写入
 *
 * @author zhaoshengtao
 * @date 2024/01/19
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false)
@Slf4j
public class ExcelWriteByDataService implements IBaseExcelWrite {

    private HSSFSheet sheet;

    public ExcelWriteByDataService(HSSFSheet sheet) {
        this.sheet = sheet;
    }
    private final Map<Object, Object> jsonCacheMap = new ConcurrentHashMap<>();
    private int idSeq = 1;

    @Override
    public void doWrite(List<?> data, Class<?> clazz, List<ExcelHeadEntity> propertyNames) throws Exception {
        this.doWrite(data, clazz, propertyNames, null, null);
    }

    @Override
    public void doWrite(List<?> data, Class<?> clazz, List<ExcelHeadEntity> propertyNames,  CellStyle cellStyle, Integer rowHeight) throws Exception {
        // 获取头
        HSSFRow row = null;//第一行
        HSSFCell cell = null;
        int i = this.idSeq;
        // 遍历实体对象集合
        for (Object t : data) {
            int j = 0;
            row = ExcelUtil.createRow(sheet, i++, rowHeight == null || rowHeight == 0 ? 250 : rowHeight);
            for (ExcelHeadEntity headEntity : propertyNames) {
                String fieldName = headEntity.getFieldName();
                boolean isJson = headEntity.isJson();
                if(isJson){
                    Optional<Field> field = Optional.ofNullable(FieldUtil.getFieldByName(clazz, fieldName));
                    if (field.isPresent()) {
                        field.get().setAccessible(true);
                        Object value = field.get().get(t);
                        if (value instanceof String) {
                            // 解析json
                            Class<?> jsonClazz = headEntity.getJsonClazz();
                            // 构建一个缓存池
                            Object jsonValue = this.jsonCacheMap.computeIfAbsent(value, k -> JSON.parseObject((String) k, jsonClazz));
                            String subFieldName = headEntity.getSubFieldName();
                            String fieldValue = FieldUtil.setFiledByName(subFieldName, headEntity.getJsonClazz(), jsonValue, headEntity);
                            cell = ExcelUtil.createCell(row, j, cellStyle);
                            cell.setCellValue(fieldValue);
                            j = j + 1;
                            continue;
                        }
                    }
                    cell = ExcelUtil.createCell(row, j, cellStyle);
                    cell.setCellValue(ExcelConstant.NULL_VALUE);
                }else{
                    // 判断是否需要多字段拼接
                    String fieldValue = "";
                    if(headEntity.isConnect()){
                         fieldValue = FieldUtil.setFiledByNames(clazz, t, headEntity);
                    }else{
                         fieldValue = FieldUtil.setFiledByName(fieldName, clazz, t, headEntity);
                    }
                    cell = ExcelUtil.createCell(row, j, cellStyle);
                    cell.setCellValue(fieldValue);

                }

                j ++;

            }
        }
        this.idSeq += data.size();
    }


}
